<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 常见this指向(this->函数的内置参数 -> 函数调用时依存的对象)
    // 1. 函数在调用时没有依存的对象(普通命名函数,匿名函数直接调用) this->window , 严格模式(this->undefind)
    // 2. 函数在调用时没有依存的对象 this->调用时依存的对象(调用时属于谁就指向谁)
    // 3. 箭头函数 没有自己的this指向 -> 依赖于父作用域的this指向


    // 那么函数调用时 this指向可以修改么?

    // 可以的!  官方提供了改变this指向的三个方法  call apply bind => 所有的函数均可以使用(除箭头函数以外),是函数的方法


    // call apply bind

    // call(thisObj,arg1,arg2...argN)
    // 1. 调用原函数
    // 2. 在本次函数执行时,强制将this指向call()方法的第一参数, 如果不传参,或者传入null,undefined => 不改变this指向
    // 3. 如果原函数需要接收参数,从第二参数开始依次向后传

    // apply(thisObj,[arg1,arg2...argN])
    // 1. 调用原函数
    // 2. 在本次函数执行时,强制将this指向apply()方法的第一参数, 如果不传参,或者传入null,undefined => 不改变this指向
    // 3. 如果原函数需要接收参数,先将参数整合到数组中,再将数组作为第二参数传入

    // bind(thisObj,arg1,arg2...argN);
    // 1. 不会调用原函数，而是根据原函数的到一个新函数
    // 2. 新函数函数调用 执行时,this始终指向bind()方法的第一参数, 如果不传参,或者传入null,undefined => 不改变this指向
    // 3. 如果原函数需要接收参数
    //    a. bind()方法指定, 从第二参数开始,依次传入  => 参数就定死了
    //    b. bind()方法并不指定,新函数调用传入  => 参数可变
    //    c. bind()方法指定一部分,新函数调用传入一部分 => 组合版 

    // 小结: 
    // call apply => 调用原函数,在本次函数执行时,强制将this指向方法的第一参数  (借鸡生蛋 -> 借用现有方法(借一次))

    // bind   => 根据原函数的到一个新函数 => (授人以鱼不如授人以渔)


    function fn(a, b) {
        console.log("函数执行了", a, b);
        console.log("this", this);
    }

    // var newFn = fn.bind(document);
    // console.log(newFn);
    // console.log(newFn === fn);  // false
    // newFn();
    // newFn();
    // newFn();

    // 关于参数
    // var newFn = fn.bind(document.body, 10, 20);
    // newFn();
    // newFn();

    // var newFn = fn.bind(document);
    // newFn(10, 20);
    // newFn(100, 200);

    var newFn = fn.bind(document.body, 10);
    newFn(20);
    newFn(200);




    // 作业
    // 1. ES6  -> Map  Set  BigInt
    // 2. 购物车 ->  自主写一遍 -> 改为事件委托(注意:事件委托只负责处理事件, 该获取的元素该是要获取的!!!)
    // 3. this
    // 4. 面向对象(!!!!!)







</script>

</html>